package dtaskboard.client.charts;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.visualizations.corechart.LineChart;
import com.google.gwt.visualization.client.visualizations.corechart.Options;

import dtaskboard.client.dto.HistoryDTO;
import dtaskboard.client.dto.SprintDTO;
import dtaskboard.client.dto.TaskDTO;
import dtaskboard.client.dto.TaskStatus;

/**
 * Classe que cria o burndownChart a partir de um sprint.
 * 
 * @author meiao
 * 
 */
public class SprintBurndownChart {

  private static final DateTimeFormat dtf = DateTimeFormat
      .getFormat("yyyyMMdd");

  public static LineChart build(SprintDTO sprint) {
    Options options = Options.create();
    options.setWidth(400);
    options.setHeight(240);
    options.setTitle("Sprint Burndown");

    int days = sprint.getDays() + 1;
    DataTable data = DataTable.create();
    data.addColumn(ColumnType.NUMBER, "Ideal");
    data.addColumn(ColumnType.NUMBER, "Real");

    data.addRows(days + 1);
    int total = sprint.getPlannedHours();
    for (int i = 0; i <= days; i++) {
      data.setValue(i, 0, total - i * total / days);
    }

    data.setValue(0, 1, total);

    Collection<TaskDTO> tasks = new ArrayList<TaskDTO>();
    for (HistoryDTO h : sprint.getHistories()) {
      tasks.addAll(h.getTasks());
    }
    Iterator<TaskDTO> it = tasks.iterator();
    while (it.hasNext()) {
      TaskDTO task = it.next();
      if (task.getStatus() != TaskStatus.DONE) {
        it.remove();
      }
    }

    int remaining = total;
    Date date = sprint.getStartDate();
    for (int i = 1; i <= days; i++) {
      it = tasks.iterator();

      while (it.hasNext()) {
        TaskDTO task = it.next();
        if (SprintBurndownChart.sameDates(task.getFinish(), date)) {
          remaining -= task.getHours();
          it.remove();
        }
      }
      data.setValue(i, 1, remaining > 0 ? remaining : 0);
      date.setTime(date.getTime() + 86400000);
      if (date.getTime() > new Date().getTime()) {
        break;
      }
    }

    return new LineChart(data, options);
  }

  private static boolean sameDates(Date d1, Date d2) {
    String s1 = SprintBurndownChart.dtf.format(d1);
    String s2 = SprintBurndownChart.dtf.format(d2);
    if (s1.equals(s2)) {
      return true;
    }
    return false;
  }

}
